home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_kernel_source / FS / FIFO.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  3.8 KB  |  161 lines

  1. /*
  2.  *  linux/fs/fifo.c
  3.  *
  4.  *  written by Paul H. Hargrove
  5.  */
  6.  
  7. #include <linux/mm.h>
  8.  
  9. static int fifo_open(struct inode * inode,struct file * filp)
  10. {
  11.     int retval = 0;
  12.     unsigned long page;
  13.  
  14.     switch( filp->f_mode ) {
  15.  
  16.     case 1:
  17.     /*
  18.      *  O_RDONLY
  19.      *  POSIX.1 says that O_NONBLOCK means return with the FIFO
  20.      *  opened, even when there is no process writing the FIFO.
  21.      */
  22.         filp->f_op = &connecting_fifo_fops;
  23.         if (!PIPE_READERS(*inode)++)
  24.             wake_up_interruptible(&PIPE_WAIT(*inode));
  25.         if (!(filp->f_flags & O_NONBLOCK) && !PIPE_WRITERS(*inode)) {
  26.             PIPE_RD_OPENERS(*inode)++;
  27.             while (!PIPE_WRITERS(*inode)) {
  28.                 if (signal_pending(current)) {
  29.                     retval = -ERESTARTSYS;
  30.                     break;
  31.                 }
  32.                 interruptible_sleep_on(&PIPE_WAIT(*inode));
  33.             }
  34.             if (!--PIPE_RD_OPENERS(*inode))
  35.                 wake_up_interruptible(&PIPE_WAIT(*inode));
  36.         }
  37.         while (PIPE_WR_OPENERS(*inode))
  38.             interruptible_sleep_on(&PIPE_WAIT(*inode));
  39.         if (PIPE_WRITERS(*inode))
  40.             filp->f_op = &read_fifo_fops;
  41.         if (retval && !--PIPE_READERS(*inode))
  42.             wake_up_interruptible(&PIPE_WAIT(*inode));
  43.         break;
  44.     
  45.     case 2:
  46.     /*
  47.      *  O_WRONLY
  48.      *  POSIX.1 says that O_NONBLOCK means return -1 with
  49.      *  errno=ENXIO when there is no process reading the FIFO.
  50.      */
  51.         if ((filp->f_flags & O_NONBLOCK) && !PIPE_READERS(*inode)) {
  52.             retval = -ENXIO;
  53.             break;
  54.         }
  55.         filp->f_op = &write_fifo_fops;
  56.         if (!PIPE_WRITERS(*inode)++)
  57.             wake_up_interruptible(&PIPE_WAIT(*inode));
  58.         if (!PIPE_READERS(*inode)) {
  59.             PIPE_WR_OPENERS(*inode)++;
  60.             while (!PIPE_READERS(*inode)) {
  61.                 if (signal_pending(current)) {
  62.                     retval = -ERESTARTSYS;
  63.                     break;
  64.                 }
  65.                 interruptible_sleep_on(&PIPE_WAIT(*inode));
  66.             }
  67.             if (!--PIPE_WR_OPENERS(*inode))
  68.                 wake_up_interruptible(&PIPE_WAIT(*inode));
  69.         }
  70.         while (PIPE_RD_OPENERS(*inode))
  71.             interruptible_sleep_on(&PIPE_WAIT(*inode));
  72.         if (retval && !--PIPE_WRITERS(*inode))
  73.             wake_up_interruptible(&PIPE_WAIT(*inode));
  74.         break;
  75.     
  76.     case 3:
  77.     /*
  78.      *  O_RDWR
  79.      *  POSIX.1 leaves this case "undefined" when O_NONBLOCK is set.
  80.      *  This implementation will NEVER block on a O_RDWR open, since
  81.      *  the process can at least talk to itself.
  82.      */
  83.         filp->f_op = &rdwr_fifo_fops;
  84.         if (!PIPE_READERS(*inode)++)
  85.             wake_up_interruptible(&PIPE_WAIT(*inode));
  86.         while (PIPE_WR_OPENERS(*inode))
  87.             interruptible_sleep_on(&PIPE_WAIT(*inode));
  88.         if (!PIPE_WRITERS(*inode)++)
  89.             wake_up_interruptible(&PIPE_WAIT(*inode));
  90.         while (PIPE_RD_OPENERS(*inode))
  91.             interruptible_sleep_on(&PIPE_WAIT(*inode));
  92.         break;
  93.  
  94.     default:
  95.         retval = -EINVAL;
  96.     }
  97.     if (retval || PIPE_BASE(*inode))
  98.         return retval;
  99.     page = __get_free_page(GFP_KERNEL);
  100.     if (PIPE_BASE(*inode)) {
  101.         free_page(page);
  102.         return 0;
  103.     }
  104.     if (!page)
  105.         return -ENOMEM;
  106.     PIPE_LOCK(*inode) = 0;
  107.     PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
  108.     PIPE_BASE(*inode) = (char *) page;
  109.     return 0;
  110. }
  111.  
  112. /*
  113.  * Dummy default file-operations: the only thing this does
  114.  * is contain the open that then fills in the correct operations
  115.  * depending on the access mode of the file...
  116.  */
  117. static struct file_operations def_fifo_fops = {
  118.     NULL,
  119.     NULL,
  120.     NULL,
  121.     NULL,
  122.     NULL,
  123.     NULL,
  124.     NULL,
  125.     fifo_open,        /* will set read or write pipe_fops */
  126.     NULL,
  127.     NULL,
  128.     NULL,
  129.     NULL
  130. };
  131.  
  132. struct inode_operations fifo_inode_operations = {
  133.     &def_fifo_fops,        /* default file operations */
  134.     NULL,            /* create */
  135.     NULL,            /* lookup */
  136.     NULL,            /* link */
  137.     NULL,            /* unlink */
  138.     NULL,            /* symlink */
  139.     NULL,            /* mkdir */
  140.     NULL,            /* rmdir */
  141.     NULL,            /* mknod */
  142.     NULL,            /* rename */
  143.     NULL,            /* readlink */
  144.     NULL,            /* readpage */
  145.     NULL,            /* writepage */
  146.     NULL,            /* bmap */
  147.     NULL,            /* truncate */
  148.     NULL            /* permission */
  149. };
  150.  
  151. void init_fifo(struct inode * inode)
  152. {
  153.     inode->i_op = &fifo_inode_operations;
  154.     PIPE_LOCK(*inode) = 0;
  155.     PIPE_BASE(*inode) = NULL;
  156.     PIPE_START(*inode) = PIPE_LEN(*inode) = 0;
  157.     PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
  158.     PIPE_WAIT(*inode) = NULL;
  159.     PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
  160. }
  161.